import "@/handsontable.less";
import { HotTable } from "@handsontable/react";
import "handsontable/dist/handsontable.full.css";
import _ from "lodash";
import { useEffect, useRef, useState } from "react";
import {
  codeNameHeaders,
  data2Map,
  tableRender,
  yesOrNoData,
  contextMenu,
  handleTableCell,
} from "./hook";
import { getMetaSorted } from "@/components/schema-form-render/utils";
import { Button } from "antd";
import { UploadOutlined } from "@ant-design/icons";
import SelectInvoice from "@/pages/invoice/components/select-invoice";
import { useVisible } from "./index";
import { toJS } from "@formily/reactive";
import ImgDialog from "./imgDialog";
import moment from "moment"
import { minus, times, divide, plus, round } from '@ey-utils/utils/numberPrecision';

const headers: any[] = ["操作"];

const columns: any = [
  {
    data: "id",
    readOnly: false,
    editable: false,
    renderer: (
      instance: any,
      td: any,
      row: any,
      col: any,
      key: any,
      value: any
    ) => {
      td.innerHTML = `<a>查看发票</a>`;
    },
  },
];

interface TypeExcelProps {
  tabConfirm: (data: any[], tag: string) => void; // 选发票的回调
  addConfirm: (tag: string) => void; // 新增的回调
  [key: string]: any;
}

var regDate =  /^((?!0000)[0-9]{4}-((0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])|(0[13-9]|1[0-2])-(29|30)|(0[13578]|1[02])-31)|([0-9]{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00)-02-29)$/;
const dateValidator = (value, callback) => {
  setTimeout(() => {
    if (regDate.test(value)) {
      callback(true);
    } else {
      callback(false);
    }
  }, 1000);
};



const TypeExcel = (props: TypeExcelProps) => {
  const hotTableComponent: any = useRef();
  const {
    cacheMetas,
    detailDataSource = [],
    modelMeta = {},
    fullDataUUID,
    dictMaps,
    shareMetas,
    saveInstance,
    disabled = false,
  } = props;

  const [tableHeaders, setTableHeaders] = useState<any>(headers);
  const [tableColumns, setTableColumns] = useState<any>(columns);
  const [buttons, setButtons] = useState<any>([]);
  const [hiddenColumns, sethiddenColumns] = useState<number[]>([]); // 隐藏字段index
  const [columnIndexs, setcolumnIndexs] = useState<any>({}); // index 和 key的映射
  const [addVisible, showAddModal, hiddenAddModal] = useVisible(false);
  const [imgVisible, showImgDialog, hiddenImgDialog] = useVisible(false);
  const [imgDataSource, setImgDataSource] = useState(null);
  // 选择发票
  const selectFapiao = () => {
    showAddModal();
  };

  // 新增行
  const add = () => {
    if (props?.addConfirm) {
      props.addConfirm(modelMeta?.tag);
    }
  };
  // 选发票之后处理发票
  const handleConfirm = async (selectRows: []) => {
    if (props?.tabConfirm) {
      props.tabConfirm(selectRows, modelMeta?.tag);
    }
  };

  const hideAddModal = () => {
    hiddenAddModal();
  };

  const btnsEventMap = {
    selectFapiao,
    add,
  };

  const btnClick = (key: string, hook: string) => {
    if (btnsEventMap && btnsEventMap[hook]) {
      btnsEventMap[hook]();
    } else {
      console?.log(`没有这个hook, ${hook}`);
      return;
    }
  };

  useEffect(() => {
    if (hotTableComponent.current?.hotInstance) {
      saveInstance?.("meta", hotTableComponent.current.hotInstance);
    }
  }, [hotTableComponent.current]);

  const handleColumn = (it: any) => {
    const col = {
      data: it.key,
      readOnly: it?.props?.readOnly || disabled,
    };
    if (it?.props?.hasOwnProperty("editable") && !it?.props?.editable) {
      col.editor = false;
    }
    return {
      ...col,
      ...handleTableCell(it, columnIndexs),
    };
  };
  const transColumn = (it: any) => {
    let header = it?.props?.select ? `${it?.label} ▼` : it?.label;
    const col = handleColumn(it);
    return {
      header,
      col,
    };
  };

  useEffect(() => {
    if (modelMeta?.pageDatas?.length > 0) {
      const newHeaders = _.cloneDeep(headers);
      const newColumns = _.cloneDeep(columns);
      const { buttons: btns, tableColumns: cols } = getMetaSorted(modelMeta);
      if (disabled) {
        setButtons([]);
      } else {
        setButtons(btns);
      }
      const colIndex: any = {};
      const hideCs: number[] = [];
      cols.forEach((item: any, index: number) => {
        if (
          item?.props?.attributes?.hasOwnProperty("editable") &&
          item?.props?.attributes?.editable === false
        ) {
          item.props.editable = false;
        } else {
          item.props.editable = !disabled;
        }

        if (item?.props?.attributes?.hasOwnProperty("readOnly")) {
          item.props.readOnly = item?.props?.attributes?.readOnly;
        } else {
          item.props.readOnly = disabled;
        }
        // 映射key 和index
        colIndex[item?.key] = index + 1;
        // 隐藏字段
        if (item.props.hidden === "1") {
          hideCs.push(colIndex[item?.key]);
        }
        const { col, header } = transColumn(item);
        col.attributes = item?.props?.attributes;
        const excelColType = item?.props?.attributes?.excelColType?.trim();
        if (excelColType) {
          if (excelColType !== "select") {
            col.type = excelColType;
          }

          if (excelColType === "date") {
            col.dateFormat =
              item?.props?.attributes?.dateFormat || "YYYY-MM-DD";
            // col.validator = dateValidator
            col.datePickerConfig = {
              i18n: {
                previousMonth: 'Previous Month',
                nextMonth: 'Next Month',
                months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
                weekdays: ['日', '一', '二', '三', '四', '五', '六'],
                weekdaysShort: ['日', '一', '二', '三', '四', '五', '六']
              }
            }
          }
        }

        if (excelColType == "select") {
          header ? newHeaders.push(header + " ▼") : null;
        } else if (excelColType == "date") {
          header ? newHeaders.push(header + ' 🕣') : null;
        } else {
          header ? newHeaders.push(header) : null;
        }
        col
          ? newColumns.push({
              ...col,
            })
          : null;
        // if (item.code !== 'sequence') {
        //     if (item.name.includes('是否')) {
        //         newHeaders.push(item.name + ' ▼');
        //         newColumns.push(tableRender(item.code, codeNameHeaders, yesOrNoData, data2Map(yesOrNoData)))
        //     } else if (item.name.includes('字典')) {
        //         newHeaders.push(item.name + ' ▼');
        //         newColumns.push(tableRender(item.code, codeNameHeaders, dict, data2Map(dict)))
        //     } else {
        //         newHeaders.push(item.name);
        //         newColumns.push({
        //             data: item.code,
        //             readOnly: false,
        //             type: item.name.includes('数字') ? 'numeric' : 'text',
        //         });
        //     }
        // }
      });
      setTableHeaders(newHeaders);
      setTableColumns(newColumns);
      sethiddenColumns(hideCs);
      setcolumnIndexs(colIndex);
    }
  }, [JSON.stringify(modelMeta?.pageDatas)]);

  const handleProps = () => {
    const { tableColumns: cols } = getMetaSorted(modelMeta);
    const obj = {};
    cols?.map((it) => {
      obj[it.key] = it;
      return it;
    });
    return {
      detailDataSource, // 数据
      columnIndexs,
      dictMaps,
      ...obj,
    };
  };

  const getImgSource = (row) => {
    const ht = hotTableComponent.current.hotInstance;
  };

  const beforeChange = (changes, source) => {
    // [[row, prop, oldVal, newVal], ...]
    // changes[0][3] = 10;
    let ht = hotTableComponent.current.hotInstance
    const data = ht.getSourceData()
    const { columnIndexs } = handleProps();
    const row = changes[0][0]
    const key = changes[0][1]
    const value = changes[0][3]
    // 验证
    const colInst:any = tableColumns?.[columnIndexs[key]];
    if(colInst?.type == 'date') {
      // console.log('***beforeChange', value, !regDate.test(value))
      if(!!value && !regDate.test(value) ) {
        setTimeout(() => {
          ht.setDataAtCell(row, columnIndexs[key], '');
        }, 500)
      }
    }

    if(colInst?.attributes?.excelColType == 'select') {
      console.log('***beforeChange', value, !/^[A-Z_]+/.test(value))
      const nameKey = `${key}Name`
      const nameValue = data[row][nameKey]
      console.log('***value', value)
      if(!!value && !/^[A-Z_]*$/.test(value) && value != 'No' && key !== 'city' && key !== 'seatClass') {
        setTimeout(() => {
          ht.setDataAtCell(row, columnIndexs[key], '');
          ht.setDataAtCell(row, columnIndexs[nameKey], '');
        }, 500)
      }
    }


    console.log('beforeChange', changes, source, data[row], colInst)
    // 处理出行天数
    if(['startDate', 'endDate'].indexOf(key) > -1) {
      const daysIndex = columnIndexs['days']

      let start = ''
      let end = ''
      if(key === 'startDate') {
        start = value
        end = data[row].endDate
      }
      if(key === 'endDate') {
        start = data[row].startDate
        end = value
      }
      if(!start || !end) {
        ht.setDataAtCell(row, daysIndex, 0);
      } else {
        // 优化：住宿租房补贴的出行天数计算不需要+1
        const days = moment(end).diff(start, 'days');
        ht.setDataAtCell(row, daysIndex,  data?.[row]?.tag === 'ZSZF' ? days: (days + 1));
      }
    }

    // 实际报销金额claimAmt 不能大于发票金额含税totalAmount
    if(key === 'claimAmt' &&  data[row].totalAmount && value > Number(data[row].totalAmount) ) {
      console.log("实际报销金额claimAmt 不能大于发票金额含税totalAmount")
      setTimeout(() => {
        ht.setDataAtCell(row, columnIndexs['claimAmt'], data[row].totalAmount);
      }, 0)
    }
    // console.log('计算人均金额 start', key, row)
    // 计算人均金额   claimAmt/particNr
    if((key === 'claimAmt' || key === 'particNr') && columnIndexs['pcapAmt'] > -1  ) {
      try {
        console.log("计算人均金额   claimAmt/particNr")
        let c = 0
        let p = 0
        let r = 0
        if(key === 'claimAmt') {
          c = value
          p = data[row].particNr
        } else {
          c = data[row].claimAmt
          p = value
        }
        if (data[row].tag === "ZD_CF" || data[row].tag === "ZD_ZSF" || data[row].tag === "ZD_Other") {
          if (p) { // 招待人数：控制正整数
            let particNr = parseInt(p);
            p = isNaN(particNr)?1:(particNr>0?particNr:1);
          }
        }
        if(Number(p) !== 0) {
          r = round(divide(c, p), 2)
        }
        setTimeout(() => {
          ht.setDataAtCell(row, columnIndexs['pcapAmt'], r);
        }, 0)
      } catch (e) {
        console.log('计算人均金额 e', e)
      }
    }
  }

  const contextMenus:any = !disabled ? contextMenu(handleProps()) : false;

  return (
      <>
        {!disabled && buttons?.length ? (
            <div>
              {buttons.map((it) => {
                return (
                    <Button
                        key={it.key}
                        icon={<UploadOutlined />}
                        onClick={() => {
                          btnClick(it.key, it?.props?.hook);
                        }}
                    >
                      {it.label}
                    </Button>
                );
              })}
            </div>
        ) : null}
        <HotTable
            ref={hotTableComponent}
            autoColumnSize
            licenseKey="non-commercial-and-evaluation"
            data={detailDataSource || []}
            rowHeaders
            // beforeKeyDown={(e) => {
            //   const ht = hotTableComponent.current.hotInstance;
            //   const selectedRange: {
            //     highlight: { col: number; row: number };
            //   } = ht.getSelectedRange()[0];
            //   const col = selectedRange?.highlight?.col;
            //   const curCel = tableColumns?.[col];
            //   const excelColType = curCel?.attributes?.excelColType;
              
            //   if (excelColType === "select" || excelColType === "date") {
            //     e.stopImmediatePropagation();
            //   }
            // }}
            afterDocumentKeyDown={(e) => {
              if(disabled) return;
              try {
                const ht = hotTableComponent.current.hotInstance;
                const selectedRange: {
                  highlight: { col: number; row: number };
                } = ht.getSelectedRange()?.[0];
                const col = selectedRange?.highlight?.col;
                const row = selectedRange?.highlight?.row;
                const curCel = tableColumns?.[col];
                const nameCol = columnIndexs?.[`${curCel?.data}Name`];
                const excelColType = curCel?.attributes?.excelColType;
                
                console.log("afterDocumentKeyDown", selectedRange, curCel, excelColType, nameCol);
                if (excelColType === "select" || excelColType === "date") {
                  e.stopImmediatePropagation();
                  setTimeout(() => {
                    ht.setDataAtCell(row, col, '');
                    if(excelColType === 'select') {
                      ht.setDataAtCell(row, nameCol, '');
                    }
                  }, 300)
                }
              } catch (error) {
                console.log(error,'afterDocumentKeyDown-error');
              }
            }}
            afterBeginEditing={(row:any, col:any)=>{
                const colInst:any = tableColumns?.[col];
                console.log('afterBeginEditing', colInst)
                if(colInst && colInst?.attributes?.excelColType === 'select'){
                  // contextMenu.executeCommand('row_below');
                  try {
                    document.querySelector("textarea").blur()
                  } catch (e) {

                  }
                  contextMenus?.items?.select?.callback(colInst.data, [{start: {row, col},end: {row, col}}], null, hotTableComponent.current.hotInstance);
                }
            }}
            beforeAutofill={(sourceRange, targetRange, selectionData) => {
              const ht = hotTableComponent.current.hotInstance;
              const rowData = ht.getDataAtRow(sourceRange.row - 1);
              const { detailDataSource, dictMaps, columnIndexs } = handleProps();
              console.log(
                  "beforeAutofill",
                  sourceRange,
                  targetRange,
                  selectionData,
                  tableColumns
              );
              for (let r = sourceRange.row; r <= targetRange.row; r++) {
                for (let c = sourceRange.col; c <= targetRange.col; c++) {
                  const key = ht.colToProp(c);
                  const nameIndex = ht.propToCol(`${key}Name`);
                  // 更新有name的key, 对应name字段的值
                  // console.log(
                  //     "columnIndexs[key]",
                  //     key,
                  //     columnIndexs[key],
                  //     tableColumns
                  // );
                  if (
                      typeof nameIndex === "number" &&
                      !tableColumns[columnIndexs[key]]?.readOnly
                  ) {
                    ht.setDataAtCell(r, nameIndex, rowData[nameIndex]);
                  }

                }
              }
            }}
            beforeChange ={beforeChange}
            afterRemoveRow={(d1, d2, d3, d4, d5) => {
              if (hotTableComponent.current) {
                let ht = hotTableComponent.current.hotInstance
                cacheMetas?.(
                    ht.getSourceData(),
                    modelMeta?.tag
                );
              }
              // if (hotTableComponent.current && data && b === "edit") {
              //   let ht = hotTableComponent.current.hotInstance
              //   cacheMetas?.(
              //       ht.getSourceData(),
              //       modelMeta?.tag
              //   );
              // }
            }}
            afterChange={(data, b) => {
              // && ["edit", "CopyPaste.paste"， "Autofill.fill"].indexOf(b) !== -1
              if (hotTableComponent.current && data) {
                let ht = hotTableComponent.current.hotInstance
                console.log('afterChange', ht.getSourceData())
                cacheMetas?.(
                    ht.getSourceData(),
                    modelMeta?.tag
                );
              }
            }}
            afterSelection={(row, column, row2, column2, preventScrolling) => {
              console.log('afterSelection', row, column, row2, column2, preventScrolling)
              // 查看发票
              if (column === 0 && column2 === 0) {
                let {
                  attachmentCode,
                  fileType,
                } = hotTableComponent.current.hotInstance.getSourceData()[row];
                showImgDialog();
                setImgDataSource({
                  imgSrc: `/afm/attachment/download?code=${attachmentCode}&optimize=false`,
                  type: fileType,
                });
              }
            }}
            stretchH="all"
            colHeaders={tableHeaders}
            columns={tableColumns}
            hiddenColumns={{
              columns: hiddenColumns,
            }}
            startRows={1}
            minRows={0}
            height='auto'
            fixedColumnsLeft={2}
            search
            fillHandle={{
              direction: "vertical",
            }}
            contextMenu={contextMenus}
        />
        {imgDataSource ? (
            <ImgDialog
                dataSource={imgDataSource}
                visible={imgVisible}
                onCancel={hiddenImgDialog}
            />
        ) : null}
        <SelectInvoice
            addVisible={addVisible}
            hiddenAddModal={hideAddModal}
            confirm={handleConfirm}
            acctCo={props?.acctCo}
            value={[]}
        />
      </>
  );
};

export default TypeExcel;
